package com.icoding.fw.utils;

import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import org.apache.log4j.Logger;

public class Encryption {
	/**
	 * Define type of Encryption Type of: SHA_1|SHA_256|SHA_384|SHA_512 SHA_1 :
	 * 160 Bit Hash SHA_256 : 256 Bit Hash SHA_384 : 384 Bit Hash SHA_512 : 512
	 * Bit Hash
	 */
	private static final Logger LOGGER = Logger.getLogger(Encryption.class);
	public static final String SHA_1 = "SHA-1";
	public static final String SHA_256 = "SHA-256";
	public static final String SHA_384 = "SHA-384";
	public static final String SHA_512 = "SHA-512";
	public static final String MD5_TYPE = "MD5";
	public static final String SECUREDERROR = "Error at secureRandom";
	public static final String GETSHAERROR = "Error at getSHASecurePW";

	/**
	 * @return
	 */
	private static String getSalt() {
		byte[] salt = null;
		try {
			SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
			salt = new byte[16];
			secureRandom.nextBytes(salt);
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error(SECUREDERROR, e);
		} catch (Exception e) {
			LOGGER.error(SECUREDERROR, e);
		}
		return salt.toString();
	}

	/**
	 * I will use this function to generate token
	 * 
	 * @param passwordNeedHash
	 * @param shaType
	 * @return
	 */
	public static String getSHASecurePassword(String passwordNeedHash,
			String shaType) {
		String generatePassword = null;
		try {
			MessageDigest messageDigest = MessageDigest.getInstance(shaType);
			messageDigest.update(getSalt().getBytes());
			byte[] bytes = messageDigest.digest(passwordNeedHash.getBytes());
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < bytes.length; i++) {
				stringBuilder.append(Integer.toString(
						(bytes[i] & 0xff) + 0x100, 16).substring(1));
			}
			generatePassword = stringBuilder.toString();
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error(GETSHAERROR, e);
		} catch (Exception e) {
			LOGGER.error(GETSHAERROR, e);
		}
		return generatePassword;
	}

	/**
	 * @param passwordNeedHash
	 * @return
	 */
	public static String getMd5SecurePassword(String passwordNeedHash) {
		StringBuffer sb = null;
		try {
			MessageDigest md = MessageDigest.getInstance(MD5_TYPE);
			md.update(passwordNeedHash.getBytes());

			byte[] byteData = md.digest();

			// convert the byte to hex format method 1
			sb = new StringBuffer();
			for (int i = 0; i < byteData.length; i++) {
				sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16)
						.substring(1));
			}
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error(SECUREDERROR, e);
		} catch (Exception e) {
			LOGGER.error(SECUREDERROR, e);
		}
		return sb.toString();
	}

	/**
	 * @param file
	 * @return
	 */
	public static String generateMd5Sum(File file) {
		StringBuffer sb = null;
		try {
			MessageDigest md = MessageDigest.getInstance(MD5_TYPE);
			FileInputStream fis = new FileInputStream(file);
			// Convert data of file to byte
			byte[] dataByte = new byte[1024];
			int nread = 0;
			while ((nread = fis.read(dataByte)) != -1) {
				md.update(dataByte, 0, nread);
			}
			byte[] mdbytes = md.digest();

			// Convert byte to the hex method
			sb = new StringBuffer();
			for (int i = 0; i < mdbytes.length; i++) {
				sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16)
						.substring(1));
			}
		} catch (NoSuchAlgorithmException e) {
			LOGGER.error(SECUREDERROR, e);
		} catch (Exception e) {
			LOGGER.error(SECUREDERROR, e);
		}
		return sb.toString();
	}

	/**
	 * @param md5Hashed
	 * @param file
	 * @return
	 */
	public static Boolean checkSumFile(String md5Hashed, File file) {
		try {
			if (generateMd5Sum(file).equalsIgnoreCase(md5Hashed)) {
				return true;
			}
		} catch (Exception e) {
			LOGGER.error(SECUREDERROR, e);
			return false;
		}
		return false;
	}
}
